﻿namespace MicroCloud.Identity
{
    /// <summary>
    /// 认证模块DTO实体映射
    /// </summary>
    public class AutoMapperIdentityConfiguration : AutoMapperTupleBase
    {
        /// <summary>
        /// 初始化一个认证模块DTO实体映射 <see cref="AutoMapperIdentityConfiguration"/> 的新实例
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public AutoMapperIdentityConfiguration(IServiceProvider provider)
        {
            ServiceProvider = provider;
        }

        #region "属性"
        #region "获取 服务提供者"
        /// <summary>
        /// 获取 服务提供者
        /// </summary>
        protected IServiceProvider ServiceProvider { get; }
        #endregion

        #endregion

        #region "方法"
        #region "创建对象映射"
        /// <summary>
        /// 创建对象映射
        /// </summary>
        public override void CreateMap()
        {
            //CreateMap<UserInputDto, User>().ForMember(mr => mr.Detail.Gender, opt => opt.MapFrom(dto => dto.Gender))
            //    .ForMember(mr => mr.Detail.Birthday, opt => opt.MapFrom(dto => dto.Birthday))
            //    .ForMember(mr => mr.Detail.BloodType, opt => opt.MapFrom(dto => dto.BloodType))
            //    .ForMember(mr => mr.Detail.Tag, opt => opt.MapFrom(dto => dto.Tag.ExpandAndToString(",")))
            //    .ForMember(mr => mr.Detail.Title, opt => opt.MapFrom(dto => dto.Title.ExpandAndToString(",")))
            //    .ForMember(mr => mr.Detail.Address, opt => opt.MapFrom(dto => dto.Address))
            //    .ForMember(mr => mr.Detail.Profile, opt => opt.MapFrom(dto => dto.Profile))
            //    .ForMember(mr => mr.Detail.Sign, opt => opt.MapFrom(dto => dto.Sign))
            //    .ForMember(mr => mr.Detail.Remark, opt => opt.MapFrom(dto => dto.Remark));
            //CreateMap<ProfileEditDto, User>().ForMember(mr => mr.Portfolio.Avatar, opt => opt.MapFrom(dto => dto.Avatar))
            //    .ForMember(mr => mr.Portfolio.Signature, opt => opt.MapFrom(dto => dto.Signature))
            //    .ForMember(mr => mr.Detail.Gender, opt => opt.MapFrom(dto => dto.Gender))
            //    .ForMember(mr => mr.Detail.Birthday, opt => opt.MapFrom(dto => dto.Birthday))
            //    .ForMember(mr => mr.Detail.BloodType, opt => opt.MapFrom(dto => dto.BloodType))
            //    .ForMember(mr => mr.Detail.Tag, opt => opt.MapFrom(dto => dto.Tag.ExpandAndToString(",")))
            //    .ForMember(mr => mr.Detail.Title, opt => opt.MapFrom(dto => dto.Title.ExpandAndToString(",")))
            //    .ForMember(mr => mr.Detail.Address, opt => opt.MapFrom(dto => dto.Address))
            //    .ForMember(mr => mr.Detail.Profile, opt => opt.MapFrom(dto => dto.Profile))
            //    .ForMember(mr => mr.Detail.Sign, opt => opt.MapFrom(dto => dto.Sign))
            //    .ForMember(mr => mr.Detail.Remark, opt => opt.MapFrom(dto => dto.Remark));
            CreateMap<User, UserOutputDto>().ForMember(mr => mr.Gender, opt => opt.MapFrom(entity => entity.Detail.Gender))
                .ForMember(mr => mr.Birthday, opt => opt.MapFrom(entity => entity.Detail.Birthday))
                .ForMember(mr => mr.BloodType, opt => opt.MapFrom(entity => entity.Detail.BloodType))
                .ForMember(mr => mr.Tag, opt => opt.MapFrom(entity => entity.Detail.Tag.Split(",", true)))
                .ForMember(mr => mr.Title, opt => opt.MapFrom(entity => entity.Detail.Title.Split(",", true)))
                .ForMember(mr => mr.Address, opt => opt.MapFrom(entity => entity.Detail.Address))
                .ForMember(mr => mr.Profile, opt => opt.MapFrom(entity => entity.Detail.Profile))
                .ForMember(mr => mr.Sign, opt => opt.MapFrom(entity => entity.Detail.Sign))
                .ForMember(mr => mr.Remark, opt => opt.MapFrom(entity => entity.Detail.Remark));

            CreateMap<Role, RoleOutputDto>().ForMember(dto => dto.CreatorName, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.CreatorId).UserName))
                .ForMember(dto => dto.CreatorNickname, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.CreatorId).NickName))
                .ForMember(dto => dto.UpdaterName, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.UpdaterId).UserName))
                .ForMember(dto => dto.UpdaterNickname, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.UpdaterId).NickName));

            CreateMap<Organization, OrganizationOutputDto>().ForMember(mr => mr.NameFrgn, opt => opt.MapFrom(entity => entity.Detail.NameFrgn))
                .ForMember(mr => mr.Address, opt => opt.MapFrom(entity => entity.Detail.Address))
                .ForMember(mr => mr.AddressFrgn, opt => opt.MapFrom(entity => entity.Detail.AddressFrgn))
                .ForMember(mr => mr.PrintHeader, opt => opt.MapFrom(entity => entity.Detail.PrintHeader))
                .ForMember(mr => mr.PrintHeaderFrgn, opt => opt.MapFrom(entity => entity.Detail.PrintHeaderFrgn))
                .ForMember(mr => mr.ReptName, opt => opt.MapFrom(entity => entity.Detail.ReptName))
                .ForMember(mr => mr.ReptNameFrgn, opt => opt.MapFrom(entity => entity.Detail.ReptNameFrgn))
                .ForMember(mr => mr.Remark, opt => opt.MapFrom(entity => entity.Detail.Remark))
                .ForMember(dto => dto.CreatorName, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.CreatorId).UserName))
                .ForMember(dto => dto.CreatorNickname, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.CreatorId).NickName))
                .ForMember(dto => dto.UpdaterName, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.UpdaterId).UserName))
                .ForMember(dto => dto.UpdaterNickname, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.UpdaterId).NickName));
            CreateMap<Organization, OrganizationNodeDto>().ForMember(mr => mr.NameFrgn, opt => opt.MapFrom(entity => entity.Detail.NameFrgn))
                .ForMember(mr => mr.Address, opt => opt.MapFrom(entity => entity.Detail.Address))
                .ForMember(mr => mr.AddressFrgn, opt => opt.MapFrom(entity => entity.Detail.AddressFrgn))
                .ForMember(mr => mr.PrintHeader, opt => opt.MapFrom(entity => entity.Detail.PrintHeader))
                .ForMember(mr => mr.PrintHeaderFrgn, opt => opt.MapFrom(entity => entity.Detail.PrintHeaderFrgn))
                .ForMember(mr => mr.ReptName, opt => opt.MapFrom(entity => entity.Detail.ReptName))
                .ForMember(mr => mr.ReptNameFrgn, opt => opt.MapFrom(entity => entity.Detail.ReptNameFrgn))
                .ForMember(mr => mr.Remark, opt => opt.MapFrom(entity => entity.Detail.Remark))
                .ForMember(dto => dto.CreatorName, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.CreatorId).UserName))
                .ForMember(dto => dto.CreatorNickname, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.CreatorId).NickName))
                .ForMember(dto => dto.UpdaterName, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.UpdaterId).UserName))
                .ForMember(dto => dto.UpdaterNickname, opt => opt.MapFrom(entity => GetUser(ServiceProvider, entity.UpdaterId).NickName));
            CreateMap<OrganizationNodeDto, OrganizationTreeNodeDto>();
            CreateMap<OrganizationTreeNodeDto, OrganizationNodeDto>();
            CreateMap<OrganizationNodeDto, OrganizationDtoSimple>();
            CreateMap<OrganizationDtoSimple, OrganizationNodeDto>();
            CreateMap<Organization, OrganizationNode>().ForMember(dto => dto.Id, opt => opt.MapFrom(entity => entity.Id.ToString()))
                .ForMember(dto => dto.ParentId, opt => opt.MapFrom(entity => entity.ParentId.HasValue ? entity.ParentId.Value.ToString() : null));
            CreateMap<OrganizationNode, OrganizationTreeNode>();
            CreateMap<OrganizationTreeNode, OrganizationNode>();
            CreateMap<OrganizationNode, OrganizationDtoSimple>();
            CreateMap<OrganizationDtoSimple, OrganizationNode>();
            CreateMap<OrganizationNode, OrganizationIdentity>();
            CreateMap<OrganizationNode, OrganizationRoleUserNode>();

        }
        #endregion

        #endregion

        #region "受保护的方法"
        #region "获取用户信息"
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="provider">服务提供者</param>
        /// <param name="userId">用户编号</param>
        /// <returns></returns>
        protected static UserSimpleDto GetUser(IServiceProvider provider, long? userId)
        {
            if (userId == null)
            {
                return new UserSimpleDto();
            }
            using IServiceScope scope = provider.CreateScope();
            var userRepository = scope.ServiceProvider.GetService<IRepository<User, long>>();
            var user = userRepository.QueryAsNoTracking().Where(o => o.Id == userId).ToCacheFirst<User, UserSimpleDto>(10, false, nameof(UserSimpleDto));
            return user ?? new UserSimpleDto();
        }
        #endregion

        #endregion

    }
}